﻿using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Infrastructure
{
    public class RedisDataDictionaryService
    {
        private readonly IDistributedCache _cache;

        public RedisDataDictionaryService(IDistributedCache cache)
        {
            _cache = cache;
        }

        /// <summary>
        /// 存储数据字典到 Redis
        /// </summary>
        public async Task SetDictionaryAsync<T>(string category, Dictionary<string, T> dict, TimeSpan? expiry = null)
            {
                try
                {
                    foreach (var kvp in dict)
                    {
                        var cacheKey = $"dict:{category}:{kvp.Key}";
                        var jsonValue = JsonConvert.SerializeObject(kvp.Value);

                        var options = new DistributedCacheEntryOptions(); 
                        if (expiry.HasValue)
                        {
                            options.SetAbsoluteExpiration(expiry.Value);
                        }

                        await _cache.SetStringAsync(cacheKey, jsonValue, options);

                        // 维护索引Key
                        var indexKey = $"dict:{category}:__allkeys__";
                        var keysJson = await _cache.GetStringAsync(indexKey);
                        var keys = string.IsNullOrEmpty(keysJson) ? new HashSet<string>() : JsonConvert.DeserializeObject<HashSet<string>>(keysJson);
                        if (!keys.Contains(kvp.Key))
                        {
                            keys.Add(kvp.Key);
                            await _cache.SetStringAsync(indexKey, JsonConvert.SerializeObject(keys), options);
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception($"Redis字典存储失败: {ex.Message}", ex);
                }
            }

        /// <summary>
        /// 从 Redis 读取整个数据字典
        /// </summary>
        public async Task<Dictionary<string, T>> GetDictionaryAsync<T>(string category)
        {
            var indexKey = $"dict:{category}:__allkeys__";
            var keysJson = await _cache.GetStringAsync(indexKey);
            if (string.IsNullOrEmpty(keysJson))
                return new Dictionary<string, T>();

            var keys = JsonConvert.DeserializeObject<HashSet<string>>(keysJson);
            var result = new Dictionary<string, T>();
            foreach (var key in keys)
            {
                var cacheKey = $"dict:{category}:{key}";
                var jsonValue = await _cache.GetStringAsync(cacheKey);
                if (!string.IsNullOrEmpty(jsonValue))
                {
                    result[key] = JsonConvert.DeserializeObject<T>(jsonValue);
                }
            }
            return result;
        }
        /// <summary>
        /// 删除指定类型的数据字典
        /// </summary>
        /// <param name="type">要删除的数据字典类型</param>
        public async Task RemoveDictionaryAsync(string type)
        {
            try
            {
                // 1. 获取该类型的所有键索引
                var indexKey = $"dict:{type}:__allkeys__";
                var keysJson = await _cache.GetStringAsync(indexKey);

                if (!string.IsNullOrEmpty(keysJson))
                {
                    // 2. 删除该类型下的所有具体键
                    var keys = JsonConvert.DeserializeObject<HashSet<string>>(keysJson);
                    foreach (var key in keys)
                    {
                        var cacheKey = $"dict:{type}:{key}";
                        await _cache.RemoveAsync(cacheKey);
                    }

                    // 3. 最后删除索引键本身
                    await _cache.RemoveAsync(indexKey);
                }

            }
            catch (Exception ex)
            {
                throw new Exception($"删除{type}类型数据字典失败: {ex.Message}", ex);
            }
        }


    }
}
